package com.qs.commontools.utils.file;

import com.qs.commontools.common.service.ImgService;
import com.qs.commontools.constants.FileConstant;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.text.DecimalFormat;

/**
 * 文件工具类
 * @author qiusuo
 * @since 2021-11-14
 */
public class FileUtils {

    /**
     * 计算文件大小，换算成KB、GB为单位的字符串。
     *
     * @param file 文件对象
     * @return 字符串 。。KB 。。GB
     */
    public static String getSize(MultipartFile file){
        long size = file.getSize();
        StringBuffer bytes = new StringBuffer();
        DecimalFormat format = new DecimalFormat(FileConstant.DECIMAL_FORMAT);
        if (size >= FileConstant.NUM_INTEGER_GB) {
            double i = (size / (FileConstant.NUM_DOUBLE_GB));
            bytes.append(format.format(i)).append(FileConstant.STR_GB);
        }
        else if (size >= FileConstant.NUM_INTEGER_MB) {
            double i = (size / (FileConstant.NUM_DOUBLE_MB));
            bytes.append(format.format(i)).append(FileConstant.STR_MB);
        }
        else if (size >= FileConstant.NUM_INTEGER_KB) {
            double i = (size / (FileConstant.NUM_DOUBLE_KB));
            bytes.append(format.format(i)).append(FileConstant.STR_KB);
        }
        else if (size < FileConstant.NUM_INTEGER_KB) {
            if (size <= FileConstant.NUM_INTEGER_ZORE) {
                bytes.append(FileConstant.STR_0B);
            }
            else {
                bytes.append((int) size).append(FileConstant.STR_B);
            }
        }
        return bytes.toString();
    }

    /**
     * 计算文件大小，换算成KB、GB为单位的字符串。
     *
     * @param file 文件对象
     * @return 字符串 。。KB 。。GB
     * @throws IOException 文件转换为MultipartFile对象异常
     */
    public static String getSize(File file) throws IOException {
        MultipartFile multipartFile = getMultipartFile(file);
        return getSize(multipartFile);
    }


    /**
     * 根据路径获得MultipartFile文件对象。
     *
     * @param path 文件路径
     * @return MultipartFile文件对象
     * @throws IOException 文件转换为MultipartFile对象异常
     */
    public static MultipartFile getMultipartFile(String path) throws IOException {
        File file = new File(path);
        return getMultipartFile(file);
    }

    /**
     * 根据File文件对象获得MultipartFile文件对象。
     *
     * @param file File类型文件
     * @return MultipartFile文件对象
     * @throws IOException 文件转换为MultipartFile对象异常
     */
    public static MultipartFile getMultipartFile(File file) throws IOException {
        if (null == file || !file.exists()) {
            throw new FileNotFoundException("文件不存在:" + file.getCanonicalPath());
        }
        String filePath = file.getCanonicalPath();
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "textField";
        int num = filePath.lastIndexOf(".");
        String extFile = filePath.substring(num);
        FileItem item = factory.createItem(file.getName(), "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        FileInputStream fis = new FileInputStream(file);
        OutputStream os = item.getOutputStream();
        while ((bytesRead = fis.read(buffer, 0, buffer.length)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        fis.close();
        MultipartFile multipartFile = new CommonsMultipartFile(item);
//        FileInputStream fileInputStream = new FileInputStream(file);
//        MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
//                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
        return multipartFile;
    }

//    /**
//     * MultipartFile对象转为File对象
//     * @param multipartFile
//     * @return 结果
//     * @throws IOException
//     */
//    public static File multipartFileToFile(MultipartFile multipartFile) throws IOException {
//        File file = new File("");
//        org.apache.commons.io.FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
//        return file;
//    }


    /**
     * 删除文件或文件夹。
     *
     * @param url 路径
     * @throws Exception 文件不存在
     */
    public static void delete(String url) throws Exception{
        File file = new File(url);
        //如果文件不存在
        if (!file.exists()) {
            throw new Exception("文件不存在");
        }else {
            // 文件存在
            //不是文件夹
            if (!file.isDirectory()){
                //是文件
                if (file.isFile()){
                    //直接删除
                    file.delete();
                }else {
                    throw new Exception("该路径既不是文件也不是文件夹");
                }
            }else {
                //是文件夹
                //获得文件夹下内容名称集合
                File[] tempList = file.listFiles();
                //如果文件夹不是空的
                if (null != tempList && tempList.length != 0){
                    //遍历内容
                    for (int i = 0; i < tempList.length; i++) {
//                        // 如果以文件夹分隔符结尾
//                        if (url.endsWith(File.separator)) {
//                            delete(url + tempList[i].getName());
//                        } else { //如果以不是以文件分隔符结尾
//                            delete(url + File.separator + tempList[i].getName());
//                        }
                        delete(tempList[i].getCanonicalPath());
                    }
                }
                //最后删除自己
                file.delete();
            }
        }
    }


    /**
     * InputStream转byte数组。
     *
     * @param inputStream 输入流
     * @throws IOException 转换异常
     * @return byte数组。
     */
    public static byte[] inputStreamToByte(InputStream inputStream) throws IOException {
        ImgService imgService = ImgService.getInstance();
        return imgService.inputStreamToByte(inputStream);
    }

    /**
     * 保存文件。
     *
     * @param multipartFile 文件对象
     * @param path 要保存的文件夹路径(不包含文件名和后缀)
     * @param name 要保存的文件名称（不带文件后缀）
     * @param suffix 文件后缀（JPG，PDF）
     * @throws IOException 保存文件异常
     */
    public static void save(MultipartFile multipartFile, String path, String name, String suffix) throws IOException {
        // 入参为文件名称和文件夹路径
        File fold = new File(path,name + "." + suffix);
        multipartFile.transferTo(fold);
    }

    /**
     * 强制保存文件。
     * <br> 文件存在就覆盖
     *
     * @param bytes 文件字节数组
     * @param path 要保存的文件夹路径(不包含文件名和后缀)
     * @param name 要保存的文件名称（不带文件后缀）
     * @param suffix 文件后缀（JPG，PDF）
     * @throws IOException 文件保存异常
     */
    public static void save(byte[] bytes, String path, String name, String suffix) throws IOException {
        if (!path.endsWith(File.separator)) {
            path = path + File.separator + name + "." + suffix;
        } else {
            path = path + name + "." + suffix;
        }
        File file = new File(path);
        //创建输出流
        FileOutputStream fileOutStream = new FileOutputStream(file);
        //写入数据
        fileOutStream .write(bytes);
    }

}
